package com.webserver6.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class HttpServletRequest {
    private Socket socket;
    private String method;
    private String uri;
    private String protocol;
    private String requestURI;
    private String queryString;
    private Map<String,String> parameters = new HashMap<>();
    private Map<String,String> headers = new HashMap<>();
    public HttpServletRequest(Socket socket) throws IOException, EmptyRequestException {
        this.socket= socket;
        parseRequestLine();
        parseHeaders();
        parseContent();
    }
    private void parseRequestLine() throws IOException, EmptyRequestException {
        String line = readLine();
        if (line.isEmpty()){
            throw new EmptyRequestException();
        }
        System.out.println("请求行内容"+line);
        String[] data = line.split("\\s");
        method=data[0];
        uri=data[1];
        protocol=data[2];
        parseURI();
        System.out.println("method"+method);
        System.out.println("uri"+uri);
        System.out.println("protocol"+protocol);
    }
    private void parseURI(){
        String[] data = uri.split("\\?");
        requestURI=data[0];
        if (data.length>1){
            queryString=data[1];
            parseParameter(queryString);
            System.out.println("requestURI"+requestURI);
            System.out.println("queryString"+queryString);
            System.out.println("parameters"+parameters);
        }
    }
    private void parseParameter(String line){
        try {
            line = URLDecoder.decode(line,"utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String[] data = line.split("&");
        for (String para : data){
            String[] arr = para.split("=",2);
            parameters.put(arr[0],arr[1]);
        }
    }
    private void parseHeaders() throws IOException {
        while (true){
            String line = readLine();
            if (line.isEmpty()){
                break;
            }
            System.out.println("消息头："+line);
            String[] data = line.split(":\\s");
            headers.put(data[0],data[1]);
        }
        System.out.println("headers:"+headers);
    }
    private void parseContent() throws IOException {
        if ("post".equalsIgnoreCase(method)){
            if (headers.containsKey("Content-Length")){
                int contentLength = Integer.parseInt(headers.get("Content-Length"));
                byte[] data = new byte[contentLength];
                InputStream in = socket.getInputStream();
                in.read(data);
                String contentType = headers.get("Content-Type");
                if ("application/x-www-form-urlencoded".equals(contentType)){
                    String line = new String(data, StandardCharsets.ISO_8859_1);
                    System.out.println("正文内容："+line);
                    parseParameter(line);
                }
            }
        }
    }
    private String readLine() throws IOException {
        InputStream in = socket.getInputStream();
        StringBuilder builder = new StringBuilder();
        char pre = 'a',cur='a';
        int d ;
        while ((d=in.read())!=-1){
            cur=(char) d;
            if (pre==13 && cur==10){
                break;
            }
            builder.append(cur);
            pre=cur;
        }
        return builder.toString().trim();
    }

    public String getMethod() {
        return method;
    }

    public String getUri() {
        return uri;
    }

    public String getProtocol() {
        return protocol;
    }

    public String getRequestURI() {
        return requestURI;
    }

    public String getQueryString() {
        return queryString;
    }

    public String getParameter(String name) {
        return parameters.get(name);
    }

    public String  getHeaders(String name) {
        return headers.get(name);
    }
}
